﻿// Copyright (c) 2009 Kjetil Eraker Samuelsen
// This source is subject to the Microsoft Public License.
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
// All other rights reserved.


using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;

using Microsoft.Win32;

using Ksamuelsen.Services.Vonage;

namespace Ksamuelsen.Office.Outlook.Addin.VDialer {
    internal class VDialerConfiguration {
        private static VDialerConfiguration _instance;
        private static object              _lock = new Object();
        private static Regex               _expr = (new Regex(Properties.Resources.CONTACT_NUMBER_ALLOWED_CHARS, RegexOptions.Compiled));


        public static VDialerConfiguration Instance {
            get {
                lock (_lock) {
                    if (_instance == null)
                        _instance = new VDialerConfiguration();
                }
                return _instance;
            }
        }

        private string _countryCode         = String.Empty;
        private string _internationalPrefix = String.Empty;
        private string _longDistancePrefix  = String.Empty;
        private string _ownNumber           = String.Empty;
        private string _displayNumber       = String.Empty;
        private string _userName            = String.Empty;
        private string _password            = String.Empty;
        private bool   _showDialog          = true;
        private bool   _showDialogWait      = true;
        private bool   _showDialogAutoClose = true;
        private bool   _ignoreExtension     = true;
        private bool   _createJournal       = false;
        private bool   _useContactCenter    = false;

        private VDialerJournalOptions _journalOptions;

        private VDialerConfiguration() {
            Load();
        }

        public string CountryCode {
            get { return _countryCode; }
            set { _countryCode = value; }
        }

        public string InternationalPrefix {
            get { return _internationalPrefix; }
            set { _internationalPrefix = value; }
        }

        public string LongDistancePrefix {
            get { return _longDistancePrefix; }
            set { _longDistancePrefix = value; }
        }


        public string OwnNumber {
            get { return _ownNumber; }
        }

        public string DisplayNumber {
            get {
                return _displayNumber;
            }
            set {
                _displayNumber = value;
                _ownNumber = Format(_displayNumber);
            }
        }

        public string UserName {
            get { return _userName; }
            set { _userName = value; }
        }

        public string Password {
            get { return _password; }
            set { _password = value; }
        }

        public bool ShowDialDialog {
            get { return _showDialog; }
            set { _showDialog = value; }
        }

        public bool ShowDialDialogWait {
            get { return _showDialogWait; }
            set { _showDialogWait = value; }
        }

        public bool ShowDialDialogAutoClose {
            get { return _showDialogAutoClose; }
            set { _showDialogAutoClose = value; }
        }

        public bool IgnoreExtension {
            get { return _ignoreExtension; }
            set { _ignoreExtension = value; }
        }

        public bool CreateJournal {
            get { return _createJournal; }
            set { _createJournal = value; }
        }

        public bool UseContactCenter {
            get { return _useContactCenter; }
            set {
                _useContactCenter = value;
                Click2Call.VonageService = (_useContactCenter ? Click2Call.Service.ContactCenter : Click2Call.Service.Click2Call);
            }
        }

        public VDialerJournalOptions JournalOptions {
            get {
                if (_journalOptions == null)
                    _journalOptions = new VDialerJournalOptions();
                return _journalOptions;
            }
        }


        public bool ConfigurationValid {
            get {
                return ((!String.IsNullOrEmpty(_userName)) && (!String.IsNullOrEmpty(_password)) && (!String.IsNullOrEmpty(_ownNumber)));
            }
        }

        public void Save() {
            Interop.CredentialsInterop.StoreCredentials(Properties.Resources.CREDENTIALS_KEY, _userName, _password);

            using (RegistryKey key = GetOrCreateKey(Properties.Resources.REG_KEY)) {
                SetRegistryStringValue(key, Properties.Resources.REG_KEY_OWN_NUMBER, DisplayNumber);

                SetRegistryStringValue(key, Properties.Resources.REG_KEY_COUNTRY_CODE, _countryCode);
                SetRegistryStringValue(key, Properties.Resources.REG_KEY_LONG_DIST_PREFIX, _longDistancePrefix);
                SetRegistryStringValue(key, Properties.Resources.REG_KEY_INTERNATIONAL_PREFIX, _internationalPrefix);

                SetRegistryBoolValue(key, Properties.Resources.REG_KEY_SHOW_DIALOG, _showDialog, "Show", "Hide");
                SetRegistryBoolValue(key, Properties.Resources.REG_KEY_SHOW_DIALOG_WAIT, _showDialogWait, "Yes", "No");
                SetRegistryBoolValue(key, Properties.Resources.REG_KEY_SHOW_DIALOG_AUTO_CLOSE, _showDialogAutoClose, "Yes", "No");
                SetRegistryBoolValue(key, Properties.Resources.REG_KEY_IGNORE_EXTENSION, _ignoreExtension, "Yes", "No");
                SetRegistryBoolValue(key, Properties.Resources.REG_KEY_CREATE_JOURNAL, _createJournal, "Yes", "No");
                SetRegistryBoolValue(key, Properties.Resources.REG_KEY_USE_CONTACT_CENTER, _useContactCenter, "Yes", "No");


                key.Close();
            }
        }

        private void Load() {
            try {
                Interop.CredentialsInterop.ReadCredentials(Properties.Resources.CREDENTIALS_KEY, out _userName, out _password);
            } catch (Exception) { }

            using (RegistryKey key = Registry.CurrentUser.OpenSubKey(Properties.Resources.REG_KEY)) {
                // Move credentials from registry, remove from registry
                if ((key != null) && ((String.IsNullOrEmpty(_userName)) && (String.IsNullOrEmpty(_password)))) {
                    _userName = (string)key.GetValue(Properties.Resources.REG_KEY_USERNAME, String.Empty);
                    _password = (string)key.GetValue(Properties.Resources.REG_KEY_PASSWORD, String.Empty);

                    if ((!String.IsNullOrEmpty(_userName)) && (!String.IsNullOrEmpty(_password))) {
                        Interop.CredentialsInterop.StoreCredentials(Properties.Resources.CREDENTIALS_KEY, _userName, _password);
                        using (RegistryKey delkey = GetOrCreateKey(Properties.Resources.REG_KEY)) {
                            delkey.DeleteValue(Properties.Resources.REG_KEY_USERNAME);
                            delkey.DeleteValue(Properties.Resources.REG_KEY_PASSWORD);

                            delkey.Close();
                        }
                    }
                }

                DisplayNumber        = GetRegistryStringValue(key, Properties.Resources.REG_KEY_OWN_NUMBER);

                _countryCode         = GetRegistryStringValue(key, Properties.Resources.REG_KEY_COUNTRY_CODE);
                _longDistancePrefix  = GetRegistryStringValue(key, Properties.Resources.REG_KEY_LONG_DIST_PREFIX);
                _internationalPrefix = GetRegistryStringValue(key, Properties.Resources.REG_KEY_INTERNATIONAL_PREFIX);
                _ignoreExtension     = GetRegistryBoolValue(key, Properties.Resources.REG_KEY_IGNORE_EXTENSION, "Yes", "No");

                _showDialog          = GetRegistryBoolValue(key, Properties.Resources.REG_KEY_SHOW_DIALOG, "Show", "Hide");
                _showDialogWait      = GetRegistryBoolValue(key, Properties.Resources.REG_KEY_SHOW_DIALOG_WAIT, "Yes", "No");
                _showDialogAutoClose = GetRegistryBoolValue(key, Properties.Resources.REG_KEY_SHOW_DIALOG_AUTO_CLOSE, "Yes", "No");

                _createJournal       = GetRegistryBoolValue(key, Properties.Resources.REG_KEY_CREATE_JOURNAL, "Yes", "No");
                UseContactCenter     = GetRegistryBoolValue(key, Properties.Resources.REG_KEY_USE_CONTACT_CENTER, "Yes", "No");

                if (key != null)
                    key.Close();
            }
        }

        private string Format(string number) {
            number.Trim();

            char[] narr = number.ToCharArray();
            StringBuilder buf = new StringBuilder();
            for (int i = 0, j = narr.Length; i < j; i++) {
                if (_expr.IsMatch(narr[i].ToString()))
                    buf.Append(narr[i]);

            }
            return buf.ToString().Trim();
        }

        internal static RegistryKey GetOrCreateKey(string name) {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(name, true);
            if (key == null)
                key = Registry.CurrentUser.CreateSubKey(name);
            return key;
        }

        internal static string GetRegistryStringValue(RegistryKey key, string prop) {
            if (key == null)
                return GetRegistryDefaultValue(prop);
            return (string)key.GetValue(GetRegistryKeyName(prop), GetRegistryDefaultValue(prop));
        }

        internal static bool GetRegistryBoolValue(RegistryKey key, string prop, string trueValue, string falseValue) {
            string value = GetRegistryStringValue(key, prop);
            if (String.IsNullOrEmpty(value))
                return false;
            return value.Equals(trueValue, StringComparison.CurrentCultureIgnoreCase);
        }

        internal static bool GetRegistryBoolValue(RegistryKey key, string prop) {
            return GetRegistryBoolValue(key, prop, "Yes", "No");
        }

        internal static void SetRegistryStringValue(RegistryKey key, string prop, string value) {
            key.SetValue(GetRegistryKeyName(prop), value, RegistryValueKind.String);
        }

        internal static void SetRegistryBoolValue(RegistryKey key, string prop, bool value, string trueValue, string falseValue) {
            string strValue = value ? trueValue : falseValue;
            SetRegistryStringValue(key, prop, strValue);
        }

        internal static void SetRegistryBoolValue(RegistryKey key, string prop, bool value) {
            SetRegistryBoolValue(key, prop, value, "Yes", "No");
        }


        internal static string GetRegistryKeyName(string value) {
            if (value.Contains("|")) {
                return value.Substring(0, value.IndexOf('|'));
            }
            return value;
        }

        internal static string GetRegistryDefaultValue(string value) {
            if (value.Contains("|")) {
                return value.Substring(value.IndexOf('|') + 1);
            }
            return string.Empty;
        }




    }
}
